Element Declarations

The first step to modeling our content is to specify our logical structure by defining the elements that will be contained within the document.  This is done using the <!ELEMENT> tag.  The syntax for the element tag is:

<!ELEMENT name content>

Let’s define the <employee> element first, since it represents an instance of an employee within the <employees> root element.

<!DOCTYPE employees [
	<!ELEMENT employee (name, position, address, phone)>
]>

What we have just stipulated is that whenever an <employee> element is encountered, it will have one <name> element, one <position> element, one <address> element and one <phone> element, in that order.  In other words, we just specified the parent/child relationships between the <employee> element and the others.  Also note that this declares that <name>, <position>, <address> and <phone> are siblings.  

The logical structure of the <employee> element.

Next, let’s specify the <name> element’s content model.

<!DOCTYPE employees [
	<!ELEMENT employee (name, position, address, phone)>
	<!ELEMENT name (first, last)>
]>

The <name> element now has two children defined: <first> and <last>.  These are required elements and the order is sequential.

The logical structure of the <name> element.

Our content model is starting to take shape.  Each <employee> element (instance of an employee) must have a name, position, address, and phone.  The name must be broken down into both first and last name.

Element Occurrence Indicators

The next two elements that we are going to model are <address> and <phone>.  These are going to be a little more complex because their internal contents (elements) are not required in our original content model.  In other words, the <address> element can contain any of the following elements, or none at all: <street>, <city>, <state> and/or <zip>.

To implement this capability in our content model, we are going to use element occurrence indicators.  Element occurrence indicators allow us to control the characteristics of an element.  Without the use of an occurrence indicator, a defined element must occur only once.  There are three element occurrence indicators.

? 	– 	indicates that the element or group of elements may be 
		omitted or occur just once.

* 	– 	indicates that that an element or group of elements may 
		be omitted or appear 1 or more times.

+ 	– 	indicates that an element or group of elements must appear 
		at least once and can appear more than one time.

To use an element occurrence indicator, append the character to the name of the element in the declaration.  Let’s show how this is done by updating our DTD to include the <employee> element.  Let’s make a rule that there must be at least one <employee> element (instance of an employee) in an XML document.  Let’s also allow for multiple <employee> elements (multiple employee instances).  

Since <employee> is a child of <employees> (the root element), we will add an <!ELEMENT> tag for the root.  The new DTD would look like this:

<!DOCTYPE employees [
	<!ELEMENT employees ( employee+ )>
	<!ELEMENT employee (name, position, address, phone)>
	<!ELEMENT name (first, last)>
]>

The new logical structure looks like this:

The logical structure of the <employees> element containing one or more <employee> elements.

Now let’s add the element declarations for the <address> child elements.  In our original content model, we made each of these elements optional, but they can appear only once in the <address> element.  The new DTD would look like this:

<!DOCTYPE employees [
	<!ELEMENT employees ( employee+ )>
	<!ELEMENT employee (name, position, address, phone)>
	<!ELEMENT name (first, last)>
	<!ELEMENT address (street?, city?, state?, zip?)>
]>

The logical structure for the <address> element now looks like this:

The logical structure of the <address> elements with its optional elements.

Finally, let’s add the element declarations for the <phone> child elements.  In our original content model, we had an open ended number of possible phone numbers based on type.  In this area, the relational model we used previously was somewhat limiting.  Let’s look at some of the ways that we can leverage XML to implement a nice content model.

The first method will define a series of phone types.  Let’s say that we want to have at least one phone number element called <main>.  Optionally, we can have a number of other phone elements called <office>, <fax>, <mobile> and <home>.  All of these other elements are optional and can appear multiple times each.  In our content model, a employee could have a main number (required), two office numbers (optional), and a fax number (optional).  The new DTD would look like this:

<!DOCTYPE employees [
	<!ELEMENT employees ( employee+ )>
	<!ELEMENT employee (name, position, address, phone)>
	<!ELEMENT name (first, last)>
	<!ELEMENT address (street?, city?, state?, zip?)>
	<!ELEMENT phone (main, office*, fax*, mobile*, home*)>
]>

The logical structure for the <phone> element now looks like this:

The logical structure of the <phone> elements with its required and optional elements.

We could have made it more open ended by creating a generic <type> and <number> element pair.  In doing so, there could be any number of phone numbers associated with an employee.  The DTD would have changed with the following line:

<!ELEMENT phone (type+, number+)>

This in turn would have affected our logical structure.

The logical structure of the <phone> elements with its required elements.

This solution would not be as controlled as there is no restriction on creating a pair of elements for each number.  While this will allow any number of phone number instances and types, it is less controlled and less readable.